﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NCP.Recruiting.ApplicationServices.Interfaces;
using NCP.Recruiting.Domain.Aggregates.Contracts;
using NCP.Recruiting.ApplicationServices.Messaging.Candidates;
using NCP.Recruiting.Domain.Aggregates.Candidates;
using NCP.Recruiting.Domain.Aggregates.Tags;
using NCP.Recruiting.ApplicationServices.ViewModels;
using NCP.Infrastructure.Common;
using NCP.Recruiting.Domain.Aggregates.Resumes;
using NCP.Recruiting.ApplicationServices.ModelConversions;
using NCP.Recruiting.ApplicationServices.Shared;
using NCP.Recruiting.Domain.Shared;

namespace NCP.Recruiting.ApplicationServices.Implementations
{
    public class CandidateAppService : ICandidateAppService
    {
        private readonly ICandidateRepository _candidateRepository;
        private readonly IResumeRepository _resumeRepository;
        private readonly ITagRepository _tagRepository;
        private readonly IContractRepository _contractRepository;

        public CandidateAppService(ICandidateRepository candidateRepository,
            IResumeRepository resumeRepository, ITagRepository tagRepository, IContractRepository contractRepository)
        {
            this._candidateRepository = candidateRepository;
            this._resumeRepository = resumeRepository;
            this._tagRepository = tagRepository;
            this._contractRepository = contractRepository;
        }

        public SearchCandidateListResponse SearchList(SearchCandidateListRequest request)
        {
            var response = new SearchCandidateListResponse();
            var status = (int)request.CandidateQueryStatus;
            try
            {
                var searchList = (from item in _candidateRepository.SearchCandidates(request.CompanyId,
                                 status, request.Keyword)
                                  select new CandidateItemViewModel()
                                  {
                                      Id = item.Id,
                                      BirthDate = item.Resume.BirthDate,
                                      Gender = item.Resume.Gender,
                                      Source = item.Source,
                                      ResumeId = item.Resume.Id,
                                      EducationLevel = item.Resume.EducationLevel,
                                      TagId = item.TagId,
                                      TagIdName = item.Tag != null ? item.Tag.TagName : "",
                                      FullName = item.Resume.FullName,
                                      JobPositionId = item.Jobposition.Id,
                                      Status = item.Status,
                                      JobTitle = item.Jobposition.JobTitle,
                                      Phone = (item.Resume.Mobile != null && item.Resume.Mobile != "") ?
                                             item.Resume.Mobile : item.Resume.Tel,
                                      YearsOfExperience = item.Resume.YearsOfExperience,
                                      Jobseekers = item.Resume.Email,
                                      InterviewJobseekers = item.Resume.Email,
                                      DateSaved = item.DateSaved,
                                      DateReviewed = item.DateReviewed,
                                      IsMarked = item.IsMarked,
                                      IsReplied = item.IsReplied,
                                      ReferenceNumber = item.Resume.ReferenceNumber,
                                      CoverLetter = item.CoverLetter,
                                      LastUpdated = item.LastUpdated
                                  });
                response.CandidateList = new PagedList<CandidateItemViewModel>(searchList, request.PageIndex,
                    request.PageSize);
                foreach (var item in response.CandidateList)
                {
                    item.ResumeReplyModel = new ResumeReplyModel()
                    {
                        TemplateId = item.TemplateId,
                        Jobseekers = item.Jobseekers,
                        Id = item.Id
                    };
                    item.InterviewModel = new InterviewModel
                    {
                        Id = item.Id,
                        InterviewJobseekers = item.InterviewJobseekers,
                        MessageTemplateId = item.MessageTemplateId
                    };
                    item.SetLovName();
                }


            }
            catch (Exception ex)
            {
                response.Exception = ex;
            }
            return response;
        }

        public ResumePrviewResponse GetPrviewItem(ResumePrviewRequest request)
        {
            var response = new ResumePrviewResponse();

            var status = (int)request.CandidateQueryStatus;
            try
            {
                var searchList = from item in _candidateRepository.SearchCandidates(request.CompanyId,
                               status, request.Keyword)
                                 select new CandidatePrviewViewModel
                                  {
                                      Id = item.Id,
                                      JobPositionId = item.JobPositionId,
                                      JobTitle = item.Jobposition.JobTitle,
                                      Remark = item.Remark,
                                      Salary = item.Salary,
                                      TagId = item.TagId,
                                      TagName = item.Tag != null ? item.Tag.TagName : string.Empty,
                                      Welfare = item.Welfare,
                                      ResumeId = item.ResumeId
                                  };
                response.CurrentItemIndex = searchList.Select(s => s.Id).ToList().IndexOf(request.CurrentId);

                _candidateRepository.UpdateItem(request.CurrentId, (item) =>
                    {
                        item.Status = 1;
                    });

                _candidateRepository.UnitOfWork.Commit();

                response.CurrentCandidate = searchList.FirstOrDefault(s => s.Id == request.CurrentId);
                response.CurrentResume = _resumeRepository.Get(response.CurrentCandidate.ResumeId).ConvertToViewModel();
                response.ResumeReplyModel = new ResumeReplyModel
                {
                    Id = response.CurrentResume.ResumeId,
                    Jobseekers = response.CurrentResume.Email,

                };
                response.InterviewModel = new InterviewModel
                {
                    Id = response.CurrentResume.ResumeId,
                    InterviewJobseekers = response.CurrentResume.Email
                };

            }
            catch (Exception ex)
            {
                response.Exception = ex;
            }
            return response;
        }

        public PrviewSaveResponse PrviewSave(PrviewSaveRequest request)
        {
            var response = new PrviewSaveResponse();
            try
            {
                response.TagId = request.CandidatePrviewViewModel.TagId;
                if (!string.IsNullOrWhiteSpace(request.CandidatePrviewViewModel.TagName))
                {
                    if (request.CandidatePrviewViewModel.TagId.HasValue)
                    {
                        var tagItem = _tagRepository.Get(request.CandidatePrviewViewModel.TagId.Value);
                        tagItem.TagName = request.CandidatePrviewViewModel.TagName;
                        tagItem.LastUpdated = DateTime.Now;
                        _tagRepository.Modify(tagItem);
                    }
                    else
                    {
                        var insertTag = new Tag
                        {
                            CompanyId = request.CompanyId,
                            DateCreated = DateTime.Now,
                            Deleted = false,
                            LastUpdated = DateTime.Now,
                            Selected = true,
                            TagName = request.CandidatePrviewViewModel.TagName
                        };
                        insertTag.GenerateNewIdentity();
                        response.TagId = insertTag.Id;
                        _tagRepository.Add(insertTag);
                    }
                }

                _candidateRepository.UpdateItem(request.CandidatePrviewViewModel.Id, (updateItem) =>
                {
                    updateItem.Salary = request.CandidatePrviewViewModel.Salary;
                    updateItem.Remark = request.CandidatePrviewViewModel.Remark;
                    updateItem.TagId = response.TagId;
                    updateItem.Welfare = request.CandidatePrviewViewModel.Welfare;
                });

                _candidateRepository.UnitOfWork.Commit();
                response.IsSuccess = true;
            }
            catch (Exception ex)
            {
                response.TagId = request.CandidatePrviewViewModel.TagId;
                response.IsSuccess = false;
                response.Exception = ex;
            }

            return response;
        }

        public DeleteResponse DeleteByIds(DeleteRequest request)
        {
            var response = new DeleteResponse();
            try
            {
                _candidateRepository.DeleteByIds(request.DeleteIds);
                response.IsSuccess = true;
            }
            catch (Exception ex)
            {
                response.Exception = ex;
                response.IsSuccess = false;
            }
            return response;
        }

        public RecoverResponse RecoverByIds(RecoverRequest request)
        {
            var response = new RecoverResponse();
            try
            {
                 _candidateRepository.RecoverByIds(request.RecoverIds);
                response.IsSuccess = true;
            }
            catch (Exception ex)
            {
                response.Exception = ex;
                response.IsSuccess = false;
            }
            return response;
        }

        public PrveNextResponse GetPrveOrNextId(PrveNextRequest request)
        {
            var response = new PrveNextResponse();
            try
            {
                var status = (int)request.CandidateQueryStatus;
                var searchList = from item in _candidateRepository.SearchCandidates(request.CompanyId,
                              status, request.Keyword)
                                 select item;
                if (request.CandidateIdList != null && request.CandidateIdList.Count > 0)
                {
                    searchList = searchList.Where(s => request.CandidateIdList.Contains(s.Id));
                }
                var currentIdList = searchList.Select(s => s.Id).ToList();

                if (request.IsPrev)
                {
                    var currentIndex = request.CurrentItemIndex - 1;
                    var index = currentIndex < 0 ?
                        currentIdList.Count - 1 : currentIndex;
                    response.CurrentId = currentIdList[index];
                }
                else
                {
                    var currentIndex = request.CurrentItemIndex + 1;
                    var index = currentIndex >= currentIdList.Count ?
                        0 : currentIndex;
                    response.CurrentId = currentIdList[index];
                }
            }
            catch (Exception ex)
            {
                response.Exception = ex;
            }
            return response;
        }

        public SetIsReadLetterResponse SetIsReadletter(SetIsReadLetterRequest request)
        {
            var response = new SetIsReadLetterResponse();
            try
            {
                var updateItem = _candidateRepository.Get(request.Id);
                updateItem.Status = 1;
                updateItem.LastUpdated = DateTime.Now;
                _candidateRepository.Modify(updateItem);
                _candidateRepository.UnitOfWork.Commit();
                response.IsScussess = true;
            }
            catch (Exception ex)
            {
                response.Exception = ex;
                response.IsScussess = false;
            }
            return response;
        }

        /// <summary>
        /// 设置"显示联系方式"的标识
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public SetShowContactFlagResponse SetShowContactFlag(SetShowContactFlagRequest request)
        {
            List<String> errors = null;

            var contract = _contractRepository.GetFiltered(x => x.Status == 1 &&
                x.EndDate >= DateTime.Today &&
                x.CompanyId.Equals(request.CompanyId)).FirstOrDefault();

            if (contract != null && contract.Resumes > 0)
            {
                var candidate = new Candidate()
                {
                    CompanyId = request.CompanyId,
                    DateCreated = DateTime.Now,
                    Deleted = false,
                    Status = 1,
                    LastUpdated = DateTime.Now,
                    ResumeId = request.ResumeId,
                    Source = (int)CandidateSourceType.Company
                };
                candidate.GenerateNewIdentity();
                _candidateRepository.Add(candidate);

                contract.Resumes = contract.Resumes - 1;
                _contractRepository.Modify(contract);
                _contractRepository.UnitOfWork.Commit();
            }
            else
            {
                errors = new List<string>();
                errors.Add("可搜索人才点数不足，无法查看联系方式");
            }
            return new SetShowContactFlagResponse() { Errors = errors };
        }
    }
}
